#include "serialportsync.h"
#include "u.h"
#include <QThread>
#include <QDebug>

SerialPortSync::SerialPortSync(QObject *parent) : QObject(parent)
{
    m_serial = new QSerialPort(this);
}

SerialPortSync::~SerialPortSync()
{
    close();
}

bool SerialPortSync::open(const QString &portName, qint32 baudRate,
                         QSerialPort::DataBits dataBits,
                         QSerialPort::Parity parity,
                         QSerialPort::StopBits stopBits,
                         QSerialPort::FlowControl flowControl)
{
    if (m_serial->isOpen()) {
        m_serial->close();
    }

    m_serial->setPortName(portName);
    m_serial->setBaudRate(baudRate);
    m_serial->setDataBits(dataBits);
    m_serial->setParity(parity);
    m_serial->setStopBits(stopBits);
    m_serial->setFlowControl(flowControl);

    m_timer = new QTimer(this);
    m_timer->setSingleShot(true);
    m_waitingForResponse = false;
    connect(m_serial, &QSerialPort::readyRead, this, &SerialPortSync::onReadyRead);
    connect(m_timer, &QTimer::timeout, this, &SerialPortSync::onTimeout);

    return m_serial->open(QIODevice::ReadWrite);
}

void SerialPortSync::close()
{
    if (m_serial->isOpen()) {
        m_serial->close();
    }
}

QByteArray SerialPortSync::sendSync(const QByteArray &data, int timeout)
{
    if (!m_serial->isOpen()) {
        return QByteArray();
    }

    // 清空接收缓冲区
    m_receiveBuffer.clear();
    m_waitingForResponse = true;
    // qDebug()<< U::getThDt() << "send data:" << data.toHex();
    // 发送数据
    qint64 bytesWritten = m_serial->write(data);
    if (bytesWritten != data.size()) {
        m_waitingForResponse = false;
        return QByteArray();
    }
    m_serial->flush();

    // 启动超时计时器
    m_timer->start(timeout);

    // 进入事件循环等待响应或超时
    QEventLoop loop;
    connect(this, &SerialPortSync::responseReceived, &loop, &QEventLoop::quit);
    connect(this, &SerialPortSync::timeoutOccurred, &loop, &QEventLoop::quit);
    loop.exec();

    return m_receiveBuffer;
}

bool SerialPortSync::isOpen() const
{
    return m_serial->isOpen();
}

void SerialPortSync::onReadyRead()
{
    if (!m_waitingForResponse) {
        return;
    }

    // 读取所有可用数据
    m_receiveBuffer += m_serial->readAll();

    // 这里可以根据实际情况添加判断条件，确定是否已经接收完所有数据
    // 例如判断是否包含结束符、达到特定长度等
    // 这里简单处理为只要收到数据就认为完成
    m_timer->stop();
    m_waitingForResponse = false;
    // qDebug()<< U::getThDt()<< "有一个接收准备的信号";
    emit responseReceived();
}

void SerialPortSync::onTimeout()
{
    m_waitingForResponse = false;
    qDebug()<< U::getThDt()<< "注意：：：：：：：：：：：：：：：：：：：：有一个超时信号";
    emit timeoutOccurred();
}
